package com.wl.common.core.web.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Date;
import java.util.Objects;

/**
 * @author: wanglin
 * @date: 2023-07-12 周三
 * @Version: 1.0
 * @Description:
 */
@Slf4j
@Data
@NoArgsConstructor
public class RestResultDTO<T> implements Serializable {
    /**
     * 调用rest后返回结果为成功
     */
    public static final Integer RESULT_SUCCESS = 0;
    /**
     * 调用rest后返回结果为失败
     */
    public static final Integer RESULT_FAIL = 1;

    @Schema(description = "返回调用结果，0-成功，1-失败")
    private Integer result;
    @Schema(description = "返回前台的信息")
    private String msg;
    @Schema(description = "返回的结果数据")
    private T data;
    @Schema(description = "异常信息")
    private String exception;
    @Schema(description = "时间戳")
    @JsonFormat(shape = JsonFormat.Shape.NUMBER)
    private Date timestamp = new Date();

    public RestResultDTO(Integer result, String msg, T data, String exception) {
        if (StringUtils.isBlank(msg)) {
            if (Objects.equals(result, RESULT_SUCCESS)) {
                msg = "操作成功";
            } else {
                msg = "操作失败";
            }
        }
        this.result = result;
        this.msg = msg;
        this.data = data;
        this.exception = exception;
    }

    public static <T> RestResultDTO<T> newSuccess() {
        return new RestResultDTO(RESULT_SUCCESS, null, null, null);
    }

    public static <T> RestResultDTO<T> newSuccess(T data) {
        return new RestResultDTO(RESULT_SUCCESS, null, data, null);
    }

    public static <T> RestResultDTO<T> newSuccess(T data, String msg) {
        return new RestResultDTO(RESULT_SUCCESS, msg, data, null);
    }

    public static <T> RestResultDTO<T> newFail(String msg) {
        return new RestResultDTO(RESULT_FAIL, msg, null, null);
    }

    public static <T> RestResultDTO<T> newFail(int code, String msg) {
        return new RestResultDTO(code, msg, null, null);
    }

    public static <T> RestResultDTO<T> newFail(String msg, String exception) {
        return new RestResultDTO(RESULT_FAIL, msg, null, exception);
    }

    public static <T> RestResultDTO<T> newFail(Exception exception, String message) {
        if (Objects.isNull(exception)) {
            return RestResultDTO.newFail("exception不能为空");
        }

        if (exception instanceof IllegalArgumentException) {
            // 断言校验异常，日志记录为warn级别
            log.warn(message, exception);
        } else if (exception instanceof NullPointerException) {
            // 空指针异常，日志记录为error级别
            log.error(message, exception);
            // 空指针异常，堆栈打印
            exception.printStackTrace();
        } else {
            // 服务调用异常，日志记录为error级别
            log.error(message, exception);
        }

        if (StringUtils.isNotBlank(message)) {
            message = "操作失败";
        }

        return new RestResultDTO<>(RESULT_FAIL, message, null, exception.getClass().getName() + ":" + exception.getMessage());
    }
}
